/**
 * 通过筛选人的特征实现过滤器模式
 */

class Person{
    constructor(name,gender,maritalStatus){
        this.name = name
        this.gender = gender
        this.maritalStatus = maritalStatus
    }

    printInfo(){
        console.log(`${this.name},${this.gender},${this.maritalStatus}`)
    }
}
//性别过滤器
class CriteriaMale{
    meetCriteria(persons){
        return persons.filter(v=>v.gender=='Male')
    }
}
//年龄过滤器
class CriteriaSingle{
    meetCriteria(persons){
        return persons.filter(v=>v.maritalStatus=='Single')
    }
}
//且 过滤器
class and{
    meetCriteria(persons,c1,c2){
        return c2.meetCriteria(c1.meetCriteria(persons))
    }
}
//或过滤器
class or{
    meetCriteria(persons,c1,c2){
        const set = new Set()
        const male = c1.meetCriteria(persons)
        const single = c2.meetCriteria(persons)
        male.forEach(v=>set.add(v))
        single.forEach(v=>set.add(v))
        return [...set]
    }
}

const persons = [];
persons.push(new Person("Robert","Male", "Single"));
persons.push(new Person("John","Male", "Married"));
persons.push(new Person("Laura","FeMale", "Married"));
persons.push(new Person("Diana","FeMale", "Single"));
persons.push(new Person("Mike","Male", "Single"));
persons.push(new Person("Bobby","Male", "Single"));

const c1 = new CriteriaMale()
const c2 = new CriteriaSingle()
const a = new and()
const o = new or()

for(let p of c1.meetCriteria(persons))
    p.printInfo()
console.log('----------------')
for(let p of c2.meetCriteria(persons))
    p.printInfo()
console.log('----------------')
for(let p of a.meetCriteria(persons,c1,c2))
    p.printInfo()
console.log('----------------')
for(let p of o.meetCriteria(persons,c1,c2))
    p.printInfo()
console.log('----------------')
